package com.lucene;

import java.io.IOException;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;

import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.classic.ParseException;

public class TestQuery {

	public static List<Map<Object, Object>> searchLucene(String index, String queryTitle, String queryBody,
			int pageIndex, int pageSize) throws IOException, ParseException {

		IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));
		IndexSearcher searcher = new IndexSearcher(reader);// 检索工具

		Sort sort = new Sort(new SortField("modifiField", SortField.Type.LONG, false));
		// Analyzer analyzer = new StandardAnalyzer();
		SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
		
		QueryParser parser = null;
		// list<map>集合
		List<Map<Object, Object>> lists = new ArrayList<>();

		//文件名检索传递
		Term term = new Term("name", queryTitle);
		Query query1 = new TermQuery(term);
		//文件内容检索传递
		parser = new QueryParser("body", analyzer);
		//Query query2 = parser.parse(queryBody);
		
		BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
		
		/*
		 * 查询条件
		 *	可满足同时单独查标题，查内容或同时查标题和内容  
		 * */
		if(("").equals(queryTitle)||queryTitle == null){
			Query query2 = parser.parse(queryBody);
			booleanQuery.add(query2, Occur.MUST);
		}else if(("").equals(queryBody)||queryBody == null){
			booleanQuery.add(query1, Occur.MUST);			
		}else{
			Query query2 = parser.parse(queryBody);
			booleanQuery.add(query1, Occur.MUST);
			booleanQuery.add(query2, Occur.MUST);
		}
		
		TopDocs results = null;
		results = searcher.search(booleanQuery.build(), 100, sort);
		for (ScoreDoc sd : results.scoreDocs) {
			Document doc = searcher.doc(sd.doc);
			lists.add(searchPutListMap(doc));
		}

		System.out.println("找到匹配的类似数据有" + lists.size() + "个");
		return lists;
	}

	public static Map<Object, Object> searchPutListMap(Document document) {
		String body = document.get("body");
		String name = document.get("name");
		String modifiedtime = document.get("modifiField");
		// 日期格式转换
		long t = Long.parseLong(modifiedtime);
		String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(t));
		Map<Object, Object> map = new HashMap<>();
		map.put("name", name);
		map.put("time", time);
		map.put("body", body);
		return map;
	}

	public static List<Map<Object, Object>> searchByName(int pageIndex, int pageSize, Query query,
			IndexSearcher searcher, Sort sort) throws IOException {
		// 第二种分页方式
		// 获取上一页的最后一个元素
		ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, query, searcher, sort);
		TopDocs tds = searcher.searchAfter(lastSd, query, pageSize, sort);
		List<Map<Object, Object>> lists = new ArrayList<>();
		for (ScoreDoc sd : tds.scoreDocs) {
			Document doc = searcher.doc(sd.doc);
			lists.add(searchPutListMap(doc));
		}
		return lists;
	}

	private static ScoreDoc getLastScoreDoc(int pageIndex, int pageSize, Query query, IndexSearcher searcher, Sort sort)
			throws IOException {
		if (pageIndex == 1)
			return null;// 如果是第一页就返回空
		int num = pageSize * (pageIndex - 1);// 获取上一页的最后数量
		TopDocs tds = searcher.search(query, num, sort);
		return tds.scoreDocs[num - 1];
	}

	public static void main(String[] args) throws IOException, ParseException {
		String index = "D:\\index";// 搜索的索引路径
		String queryTitle =""; // 搜索的标题索引名称
		String queryBody ="你好"; // 搜索的内容索引名称
		if ((queryTitle.equals("") || queryTitle == null) && (queryBody.equals("") || queryBody == null)) {
			return;
		}
		int pageIndex = 1;// 第几页
		int pageSize = 100;// 每页显示多少数据
		List<Map<Object, Object>> lists = searchLucene(index, queryTitle, queryBody, pageIndex, pageSize);
		for (Map<Object, Object> map : lists) {
			System.out.println("文件名：" + map.get("name"));
			System.out.println("日期：" + map.get("time"));
			System.out.println("文件内容：" + map.get("body"));
		}
	}
}